#include "JctoArgv.h"
#include "JctoYing.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static int set(JctoArgv*arg,const char k[],const char v[])
{
    if(strcmp(k,"dataNames")==0){strcpy(arg->dataNames,v);}
    else if(strcmp(k,"outputDir")==0){strcpy(arg->outputDir,v);}
    else if(strcmp(k,"loadModelDir")==0){strcpy(arg->loadModelDir,v);}
    else if(strcmp(k,"deviceIdS")==0){strcpy(arg->deviceIdS,v);}
    else if(strcmp(k,"epoch")==0){strcpy(arg->epoch,v);}
    else if(strcmp(k,"driver")==0){strcpy(arg->driver,v);}
    else if(strcmp(k,"conda")==0){strcpy(arg->conda,v);}
    else
    {
        hxPrintf("unknown %s\n",k);
        exit(0);
    }
    return 1;
}

static void cut(const char a[],char k[],char v[])
{
    if(a[0]=='-'&&a[1]=='-')
    {
        int j=2,kl=0,vl=0;
        for(;a[j]&&a[j]!='=';k[kl]=a[j],++j,++kl){}
        if(a[j]=='=')
        {
            ++j;
            for(;a[j];v[vl]=a[j],++j,++vl){}
        }
        k[kl]=v[vl]=0;
    }
}

static void lookEnvp(char**envp,char*v)
{
    if(v&&(v[0]=='$'||v[0]=='%'))
    {
        if(getenv(v+1)!=NULL)
        {
            strcpy(v,getenv(v+1));
        }else if(envp)
        {
            for(int i=0;envp[i];++i)
            {
                int j=0;
                for(;envp[i][j]&&envp[i][j]!='='&&v[j+1]&&v[j+1]==envp[i][j];++j){}
                if(envp[i][j]=='='&&v[j+1]==0)
                {
                    strcpy(v,envp[i]+j+1);
                }
            }
        }
        if(v[0]=='$'||v[0]=='%')
        {
            hxPrintf("unknown %s\n",v);
            exit(0);
        }
    }
}

static void decode(JctoArgv*arg,const char a[],char**envp)
{
    char k[8192],v[8192];
    cut(a,k,v);
    if(v[0]=='$'||v[0]=='%')
    {
        lookEnvp(envp,v);
    }
    if(strcmp(k,"include")==0)
    {
        FILE*fp=fopen(v,"rb");
        if(fp)
        {
            char tmp[1024];
            while(fscanf(fp,"%1023s",tmp)!=EOF)
            {
                decode(arg,tmp,envp);
            }
            fclose(fp);
        }else
        {
            hxPrintf("failed to open %s\n",v);
        }
    }else
    {
        set(arg,k,v);
    }

}

void jctoArgvDecode(JctoArgv*arg,int argc,char**argv,char**envp)
{
    memset(arg,0,sizeof(JctoArgv));
    for(int i=1;i<argc;++i)
    {
        decode(arg,argv[i],envp);
    }
}

void jctoArgvSave(const JctoArgv*arg,FILE*fp)
{
    if(arg->dataNames[0]){hxFPrintf(fp,"%s=%s\n","--dataNames",arg->dataNames);}
    if(arg->outputDir[0]){hxFPrintf(fp,"%s=%s\n","--outputDir",arg->outputDir);}
    if(arg->loadModelDir[0]){hxFPrintf(fp,"%s=%s\n","--loadModelDir",arg->loadModelDir);}
    if(arg->deviceIdS[0]){hxFPrintf(fp,"%s=%s\n","--deviceIdS",arg->deviceIdS);}
    if(arg->epoch[0]){hxFPrintf(fp,"%s=%s\n","--epoch",arg->epoch);}
    if(arg->driver[0]){hxFPrintf(fp,"%s=%s\n","--driver",arg->driver);}
    if(arg->conda[0]){hxFPrintf(fp,"%s=%s\n","--conda",arg->conda);}
}
